package com.wennn.top.core.mybatisplus;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wennn.top.common.util.BeanUtils;
import com.wennn.top.core.mybatisplus.anno.Query;
import com.wennn.top.web.user.dto.YxUserDto;
import com.wennn.top.web.user.vo.UserVo;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @description:
 * @author: wennn
 * @date: 7/7/20
 */

@Slf4j
public class QueryBuilder {

    public static void main(String[] args) {

        YxUserDto entity = new YxUserDto();
        entity.setAvatar("dddds");
        UserVo userVo = BeanUtils.copyByReflectField(entity, UserVo.class);
        System.out.println(userVo);
//        entity.setAges(new Integer[]{1, 3});
//        entity.setAddress(new String[]{"a", "b"});
//        entity.setDa(new Date[]{new Date(), new Date()});
//        LambdaQueryWrapper<YxUser> build = builder(entity);

    }

    public static <T> LambdaQueryWrapper builder(T entity) {
        QueryWrapper<?> queryWrapper = Wrappers.query();
        try {
            List<Field> fields = BeanUtils.getAllFields(entity.getClass(), new ArrayList<>());
            for (Field field : fields) {
                boolean accessible = field.isAccessible();
                field.setAccessible(true);
                Query q = field.getAnnotation(Query.class);
                if (q != null) {
                    String dbName = q.dbName();
                    String blurry = q.blurry();
                    String attributeName = isBlank(dbName) ? StringUtils.camelToUnderline(field.getName()) : dbName;
                    Class<?> fieldType = field.getType();
                    Object val = field.get(entity);

                    if (Objects.isNull(val) || "".equals(val)) {
                        continue;
                    }

                    System.out.printf("属性：%s,表字段：%s,类型：%s,值：%s \n", field.getName(), attributeName, fieldType, val);

                    // 模糊多字段
                    if (!isBlank(blurry)) {
                        String[] blurrys = blurry.split(",");
                        for (String s : blurrys) {
                            String attr = StringUtils.camelToUnderline(s);
                            queryWrapper.like(attr, val);
                        }
                        continue;
                    }
                    Object[] valArr = null;
                    if (fieldType.isArray()) {
                        valArr = (Object[]) val;
                    } else if (val instanceof String) {
                        valArr = ((String) val).split(",");
                    }
                    switch (q.type()) {
                        case EQ:
                            queryWrapper.eq(attributeName, val);
                            break;
                        case NE:
                            queryWrapper.ne(attributeName, val);
                            break;
                        case GT:
                            queryWrapper.gt(attributeName, val);
                            break;
                        case GE:
                            queryWrapper.ge(attributeName, val);
                            break;
                        case LT:
                            queryWrapper.lt(attributeName, val);
                            break;
                        case LE:
                            queryWrapper.le(attributeName, val);
                            break;
                        case BETWEEN:
                            if (!Objects.isNull(valArr)) {
                                queryWrapper.between(attributeName, valArr[0], valArr[1]);
                            }
                            break;
                        case NOTBETWEEN:
                            if (!Objects.isNull(valArr)) {
                                queryWrapper.notBetween(attributeName, valArr[0], valArr[1]);
                            }
                            break;
                        case LIKE:
                            queryWrapper.like(attributeName, val);
                            break;
                        case NOTLIKE:
                            queryWrapper.notLike(attributeName, val);
                            break;
                        case LIKELEFT:
                            queryWrapper.likeLeft(attributeName, val);
                            break;
                        case LIKERIGHT:
                            queryWrapper.likeRight(attributeName, val);
                            break;
                        case ISNULL:
                            queryWrapper.isNull(attributeName);
                            break;
                        case ISNOTNULL:
                            queryWrapper.isNotNull(attributeName);
                            break;
                        case IN:
                            queryWrapper.in(attributeName, val);
                            break;
                        case NOTIN:
                            queryWrapper.notIn(attributeName, val);
                            break;
                        case INSQL:
                            queryWrapper.inSql(attributeName, val.toString());
                            break;
                        case NOTINSQL:
                            queryWrapper.notInSql(attributeName, val.toString());
                            break;
                        case GROUPBY:
                            queryWrapper.groupBy(attributeName);
                            break;
                        case ORDERBYASC:
                            queryWrapper.orderByAsc(attributeName);
                            break;
                        case ORDERBYDESC:
                            queryWrapper.orderByDesc(attributeName);
                            break;
                        default:
                            break;
                    }
                }
                field.setAccessible(accessible);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return queryWrapper.lambda();
    }


    private static boolean isBlank(final CharSequence cs) {
        int strLen;
        if (cs == null || (strLen = cs.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if (!Character.isWhitespace(cs.charAt(i))) {
                return false;
            }
        }
        return true;
    }

}
